using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
using SharpSoft.Data.GSQL;
using System.IO;

namespace SharpSoft.Data.DAOS
{ 
    public class AccountsDAO : DAO
    {
        protected override string InitScriptFileName => "accounts.txt";

        public AccountsDAO(Database p_db, int p_userid) : base(p_db, p_userid)
        {
        }
        #region Roles
        public class Role
        {
            public Role()
            {

            }
            public Role(int id, string name)
            {
                this.Id = id;
                this.Name = name;
            }
            public int Id { get; set; }
            public string Name { get; set; }
        }

        /// <summary>
        /// 获取系统定义的所有角色
        /// </summary>
        /// <returns></returns>
        public Role[] GetRoles()
        {
            string sql = $"SELECT * FROM `Account_Roles`;";
            var array = db.ExecuteArray<Role>(sql);
            return array;
        }
        /// <summary>
        /// 获取用户的角色位标识
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public int GetUserRoleFlag(int uid)
        {
            string sql = $"SELECT `RoleFlag` FROM `Account_Users` WHERE `Id`={uid};";
            var roleflag = db.ExecuteScalar<int?>(sql);
            if (!roleflag.HasValue)
            {
                throw new Exception("用户不存在。");
            }
            return roleflag.Value;
        }
        /// <summary>
        /// 获取用户拥有的角色
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public Role[] GetUserRoles(int uid)
        {
            var roleflag = GetUserRoleFlag(uid);
            string sql = $"SELECT * FROM `Account_Roles` WHERE (`Id` & @roleflag)=`Id`;";
            var array = db.ExecuteArray<Role>(sql, new { roleflag });
            return array;
            //以下写法效率不好
            //var roleflag = this.GetRoleFlag(uid);
            //var roles = this.GetRoles();
            //if (roles = null || roles.Length = 0)
            //{//系统未定义角色，获取用户角色没有意义
            //    throw new Exception("系统未定义任何角色。");
            //}
            //List<Role> list = new List<Role>();
            //foreach (var item in roles)
            //{
            //    if ((roleflag & item.Id) = item.Id)
            //    {
            //        list.Add(item);
            //    }
            //}
            //return list.ToArray();
        }
        /// <summary>
        /// 获取角色信息
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        public Role GetRole(int rid)
        {
            string sql = $"SELECT * FROM `Account_Roles` WHERE `Id`={rid};";
            var role = db.ExecuteObject<Role>(sql);
            return role;
        }
        /// <summary>
        /// 插入角色
        /// </summary>
        /// <param name="roleid"></param>
        /// <param name="rolename"></param>
        /// <returns></returns>
        public int InsertRole(int roleid, string rolename)
        {
            if (roleid <= 0)
            {
                throw new Exception("角色Id不能为0且不能小于0.");
            }
            var ZS = Math.Log(roleid, 2);//求roleid的平方指数
            if (ZS != Math.Ceiling(ZS))
            {
                throw new Exception("角色Id必须是2的N次方。");
            }
            string sql = "INSERT INTO `Account_Roles`(`Id`,`Name`)VALUES(@Id,@Name);SELECT LAST_INSERT_ID();";
            var rid = db.ExecuteInt32(sql, new { Id = roleid, Name = rolename });
            return rid;
        }
        /// <summary>
        /// 是否存在指定名称的角色
        /// </summary>
        /// <param name="rname"></param>
        /// <returns></returns>
        public bool ExistsRoleName(string rname)
        {
            string sql = "SELECT COUNT(`Id`) FROM `Account_Roles` WHERE `Name`=@Name";
            var count = db.ExecuteInt32(sql, new { Name = rname });
            return count > 0;
        }
        /// <summary>
        /// 更改角色名称
        /// </summary>
        /// <param name="roleid"></param>
        /// <param name="rolename"></param>
        public void UpdateRoleName(int roleid, string rolename)
        {
            string sql = "UPDATE `Account_Roles` SET `Name`=@Name WHERE `Id`=@Id;";
            db.ExecuteNonQuery(sql, new { Id = roleid, Name = rolename });
        }
        /// <summary>
        /// 删除指定的角色
        /// </summary>
        /// <param name="roleid"></param>
        public void DeleteRole(int roleid)
        {
            throw new NotSupportedException("正常情况下，角色一经创建就不允许再删除，删除已被用户引用的角色会导致系统逻辑错误。");
            //string sql = $"SELECT COUNT(`Id`) FROM `Account_Users` WHERE `RoleId`={roleid}";
            //var count = db.ExecuteInt32(sql);
            //if (count > 0)
            //{//角色有被使用
            //    throw new Exception("角色有指定给用户，无法删除。");
            //}
            //string sqldel = $"DELETE FROM `Account_Roles` WHERE `Id`={roleid};";
            //db.ExecuteNonQuery(sqldel);
        }

        #endregion

        #region Users
        public class User
        {
            public int Id { get; set; }

            public string Ticket { get; set; }

            public int RoleFlag { get; set; }

            public string Name { get; set; }

            public int Status { get; set; }

            public DateTime CreateTime { get; set; }

            public string DisplayName { get; set; }
        }

        /// <summary>
        /// 检查用户状态，异常（小于0）则报错
        /// </summary>
        /// <param name="uid"></param>
        public void EnsureUserStatus(int uid)
        {
            string sql = $"SELECT Count(*) FROM `Account_Users` WHERE `Id`={uid} AND `Status`>=0 AND (`BanTime` IS NULL OR `BanTime`>=NOW());";
            var count = db.ExecuteInt32(sql);
            if (count == 0)
            {
                throw new Exception("账号已被封停。");
            }
        }
        /// <summary>
        /// 获取账号封停到的时间点
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public DateTime? GetBanTime(int uid)
        {
            var sql = $"SELECT `BanTime` FROM `Account_Users` WHERE `Id`={uid};";
            return db.ExecuteScalar<DateTime?>(sql);
        }

        /// <summary>
        /// 是否存在用户
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public bool ExistsUser(int uid)
        {
            string sql = $"SELECT Count(*) FROM `Account_Users` WHERE `Id`={uid};";
            return db.ExecuteInt32(sql) > 0;
        }
        /// <summary>
        /// 检查用户名是否存在
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool ExitsUserName(string username)
        {
            var uid = GetUserIdByName(username);
            return uid.HasValue;
        
        }
        /// <summary>
        /// 根据用户名获取用户Id
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public int? GetUserIdByName(string username)
        {
            string sql = $"SELECT `Id` FROM `Account_Users` WHERE `Name`=@Name;";
            var id = db.ExecuteScalar<int?>(sql, new { Name = username });
            return id;
        }
        /// <summary>
        /// 获取用户名
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public string GetUserName(int uid)
        {
            if (uid == -1)
            {
                return "*系统账户*";
            }
            string sql = $"SELECT `Name` FROM `Account_Users` WHERE `Id`=@uid;";
            var name = db.ExecuteString(sql, new { uid });
            return name;
        }
        /// <summary>
        /// 根据ticket获取用户Id
        /// </summary>
        /// <param name="ticket"></param>
        /// <returns></returns>
        public int? GetUserIdByTicket(string ticket)
        {
            string sql = $"SELECT `Id` FROM `Account_Users` WHERE `Ticket`=@ticket;";
            var uid = db.ExecuteScalar<int?>(sql, new { ticket });
            return uid;
        }

        /// <summary>
        /// 获取用户登录的ticket
        /// </summary>
        /// <returns></returns>
        public string GetUserTicket(int uid)
        {
            string sql = $"SELECT `Ticket` FROM `Account_Users` WHERE `Id`=@uid;";
            var ticket = db.ExecuteString(sql, new { uid });
            return ticket;
        }
        /// <summary>
        /// 设置用户的ticket
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="ticket"></param>
        public void SetUserTicket(int uid, string ticket)
        {
            string sql = $"UPDATE `Account_Users` SET `Ticket`=@ticket WHERE `Id`=@uid;";
            db.ExecuteNonQuery(sql, new { uid, ticket });
        }
        /// <summary>
        /// 获取全系统用户数量
        /// </summary>
        /// <returns></returns>
        public int GetUsersCount()
        {
            string sql = $"SELECT COUNT(*) FROM `Account_Users`;";
            var count = db.ExecuteInt32(sql);
            return count;
        }

        public User GetUser(int userid)
        {
            var sql =
$@"SELECT *  FROM `Account_Users` WHERE `Id`={userid};";
            var user = db.ExecuteObject<User>(sql);
            return user;
        }
        /// <summary>
        /// 获取用户状态
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public int GetUserStatus(int userid)
        {
            var sql = $@"SELECT `Status` from `Account_Users` WHERE  `Id`={userid};";
            var status = db.ExecuteInt32(sql);
            return status;
        }
        /// <summary>
        /// 插入新的账号
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pwd_md5"></param>
        /// <param name="roleflag"></param>
        /// <returns></returns>
        public int InsertAccount(string name, string pwd_md5, int roleflag)
        { 
            var ticket = "";
            do
            {//生成用户的唯一ticket
                ticket = Guid.NewGuid().ToString();
                var u = GetUserIdByTicket(ticket);
                if (!u.HasValue)
                {
                    break;
                }
            } while (true);

            string sql = "INSERT INTO `Account_Users`(`Name`,`Password`,`RoleFlag`,`Ticket`)VALUES(@Name,@Password,@RoleFlag,@Ticket);SELECT LAST_INSERT_ID();";
            int uid = db.ExecuteInt32(sql, new { Name = name, Password = pwd_md5, RoleFlag = roleflag, Ticket = ticket });
            return uid;
        }
        /// <summary>
        /// 更新用户的唯一名称
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="name"></param>
        public void UpdateUserName(int uid, string name)
        {
            var sql = "UPDATE `Account_Users` SET `Name`=@name WHERE `Id`=@uid;";
            db.ExecuteNonQuery(sql, new { uid, name });
        }
        /// <summary>
        /// 更新用户的显示名称
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="disname"></param>
        public void UpdateUserDisplayName(int uid, string disname)
        {
            var sql = "UPDATE `Account_Users` SET `DisplayName`=@disname WHERE `Id`=@uid;";
            db.ExecuteNonQuery(sql, new { uid, disname });
        }
        /// <summary>
        /// 更新用户的角色标识
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="roleflag"></param>
        public void UpdateUserRoleFlag(int uid,int roleflag)
        {
            var sql = "UPDATE `Account_Users` SET `RoleFlag`=@roleflag WHERE `Id`=@uid;";
            db.ExecuteNonQuery(sql, new { uid, roleflag });
        }

        [Obsolete("一般情况下不允许删除用户数据")]
        public void DeleteUser(int userid)
        {
            string sql = $"DELETE FROM `Account_Users` WHERE `Id`={userid};";
            db.ExecuteNonQuery(sql);
        } 
        /// <summary>
        /// 更新用户状态
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="userStatus"></param>
        public void UpdateUserStatus(int uid, int userStatus)
        {
            string sql = $"UPDATE `Account_Users` SET `Status`={userStatus} WHERE `Id`={uid}";
            db.ExecuteNonQuery(sql);
        }

        public void UpdateUserStatus(int uid, UserStatus userStatus)
        {
            UpdateUserStatus(uid, (int)userStatus);
        }

        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="pwd_md5"></param>
        public void UpdateUserPassword(int uid, string pwd_md5)
        {
            string sql = $"UPDATE `Account_Users` SET `Password`=@Password WHERE `Id`={uid}";
            db.ExecuteNonQuery(sql, new { Password = pwd_md5 });

        }
        /// <summary>
        /// 匹配用户名密码
        /// </summary>
        /// <param name="uname">用户名</param>
        /// <param name="pwd_md5">密码</param>
        /// <returns>反回用户Id</returns>
        public int? MatchPassword(string uname, string pwd_md5)
        {
            string sql = "SELECT `Id` FROM `Account_Users` WHERE `Name`=@Name AND `Password`=@Password;";
            var userid = db.ExecuteScalar<int?>(sql, new { Name = uname, Password = pwd_md5 });
            return userid;
        }
        /// <summary>
        /// 匹配用户名密码
        /// </summary>
        /// <param name="uname">用户名</param>
        /// <param name="pwd_md5">密码</param>
        /// <returns>反回用户Id</returns>
        public void MatchPassword(int uid, string pwd_md5)
        {
            string sql = "SELECT COUNT(*) FROM `Account_Users` WHERE `Id`=@Id AND `Password`=@Password;";
            var COUNT = db.ExecuteScalar<int>(sql, new { Id = uid, Password = pwd_md5 });
            if (COUNT == 0)
            {
                throw new Exception("用户不存在或密码不正确。");
            }
        }
        /// <summary>
        /// 匹配当前用户的密码
        /// </summary>
        /// <param name="pwd_md5"></param>
        /// <returns></returns>
        public void MatchPassword(string pwd_md5)
        {
            string sql = $"SELECT `Id` FROM `Account_Users` WHERE `Password`=@Password AND `Id`={this.userid};";
            var userid = db.ExecuteScalar<int?>(sql, new { Password = pwd_md5 });
            if (!userid.HasValue)
            {
                throw new Exception("当前密码不正确。");
            }
        }
        #endregion

        #region Permissions
        public class Permission
        {
            public int Id { get; set; }

            public string Name { get; set; }

            public int RoleId { get; set; }

            public bool Enabled { get; set; }
        }
        /// <summary>
        /// 获取角色位标识所拥有的权限
        /// </summary>
        /// <param name="roleflag"></param>
        /// <returns></returns>
        public Permission[] GetPermissions(int roleflag)
        {
            string sql = $"SELECT * FROM `Account_Permissions` WHERE (`RoleId`&@roleflag)=`RoleId`;";
            var array = db.ExecuteArray<Permission>(sql, new { roleflag });
            return array;
        }
        /// <summary>
        /// 设置角色的权限
        /// </summary>
        /// <param name="roleid"></param>
        /// <param name="area"></param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <param name="enabled"></param>
        public void SetPermission(int roleid, string action, string controller, string area, bool enabled)
        {
            var obj = new { RoleId = roleid, Area = area, Controller = controller, Action = action, Enabled = enabled };
            string sqlcount = "SELECT COUNT(*) FROM `Account_Permissions` WHERE `Area`=@Area AND `Controller`=@Controller AND `Action`=@Action AND `RoleId`=@RoleId;";
            var count = db.ExecuteInt32(sqlcount, obj);
            if (count == 0)
            {
                string sqlinsert = "INSERT INTO `Account_Permissions`(`Area`, `Controller`, `Action`,`RoleId`,`Enabled`)VALUES(@Area,@Controller,@Action,@RoleId,@Enabled);";
                db.ExecuteNonQuery(sqlinsert, obj);
            }
            else
            {
                string sqlupdate = "UPDATE `Account_Permissions` SET `Enabled`=@Enabled WHERE `Area`=@Area AND `Controller`=@Controller AND `Action`=@Action AND `RoleId`=@RoleId;";
                db.ExecuteNonQuery(sqlupdate, obj);
            }
        }

        #endregion

        #region LoginDeviceInfo
        /// <summary>
        /// 插入或更新登录设备信息
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="DeviceType"></param>
        /// <param name="Fingerprint"></param>
        /// <param name="DeviceData"></param>
        /// <param name="Display"></param>
        /// <param name="Token"></param>
        /// <param name="LastLoginTime"></param>
        public int SetLoginDevice(int UserId, string DeviceType, string Fingerprint, string DeviceData, string Display, string Token)
        {
            var sqlsel = $@"SELECT `Id` FROM `Account_LoginDevice` WHERE `UserId`=@UserId AND `Fingerprint`=@Fingerprint;";
            var lid = db.ExecuteScalar<int?>(sqlsel, new { Fingerprint, UserId });
            if (lid.HasValue)//此设备已有记录
            {
                var sql = $@"UPDATE `Account_LoginDevice` SET `DeviceType`=@DeviceType,`DeviceData`=@DeviceData,`Display`=@Display,`Token`=@Token,`TokenUpdateTime`=NOW(),`LastLoginTime`=NOW() WHERE `Id`=@Id;";
                db.ExecuteNonQuery(sql, new { lid.Value, UserId, DeviceType, Fingerprint, DeviceData, Display, Token });
                return lid.Value;
            }
            else
            {
                var sql = $@"INSERT INTO `Account_LoginDevice`(`UserId`,`DeviceType`,`Fingerprint`,`DeviceData`,`Display`,`Token`)VALUES(@UserId,@DeviceType,@Fingerprint,@DeviceData,@Display,@Token);SELECT LAST_INSERT_ID();";
                return db.ExecuteInt32(sql, new { UserId, DeviceType, Fingerprint, DeviceData, Display, Token });
            }

        }
        /// <summary>
        /// 删除登录设备
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public int DeleteLoginDevice(int Id)
        {
            var sql = $@"DELETE FROM `Account_LoginDevice` WHERE `Id`=@Id;";
            return db.ExecuteNonQuery(sql, new { Id });
        }
        /// <summary>
        /// 更新设备上次登录时间
        /// </summary>
        public void UpdateDeviceLastLoginTime(int Id)
        {

            var sql = $@"UPDATE `Account_LoginDevice` SET `LastLoginTime`=NOW() WHERE `Id`=@Id;";
            db.ExecuteNonQuery(sql, new { Id });
        }
        /// <summary>
        /// 更改用户设备登录的Token
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="Fingerprint"></param>
        /// <param name="Token"></param>
        public void UpdateLoginDeviceToken(int UserId, string Fingerprint, string Token)
        {
            var sql = $@"UPDATE `Account_LoginDevice` SET Token=@Token,`TokenUpdateTime`=NOW() WHERE `UserId`=@UserId AND `Fingerprint`=@Fingerprint;";
            db.ExecuteNonQuery(sql, new { UserId, Fingerprint, Token });
        }
        /// <summary>
        /// 匹配设备指纹和token,匹配成功返回用户的id，失败则抛出异常。
        /// </summary>
        /// <param name="Fingerprint"></param>
        /// <param name="Token"></param>
        /// <param name="tokenIndate"></param>
        /// <returns></returns>
        public int MatchLoginDeviceToken(string Fingerprint, string Token, TimeSpan tokenIndate, out int loginDeviceId)
        {
            var sql = $@"SELECT `Id`,`UserId`,`TokenUpdateTime`,NOW() AS `dbNow` FROM `Account_LoginDevice` WHERE `Fingerprint`=@Fingerprint AND Token=@Token;";
            var obj = db.ExecuteJObject(sql, new { Fingerprint, Token });
            if (obj == null)
            {
                throw new Exception("无效的设备信息，请重新登录。");
            }
            var uid = obj["UserId"].ToObject<int>();
            loginDeviceId = obj["Id"].ToObject<int>();
            var tokenTime = obj["TokenUpdateTime"].ToObject<DateTime>();
            var dbNow = obj["dbNow"].ToObject<DateTime>();
            if (dbNow - tokenTime > tokenIndate)
            {//token已经超过了有效期。
                throw new Exception("设备登录信息已过期，请重新登录。");
            }
            return uid;
        }


        #endregion

        #region  Logs
        /// <summary>
        /// 插入登录记录
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="IsSuccess"></param>
        /// <param name="Message"></param>
        /// <param name="LoginTime"></param>
        /// <param name="IpAddress"></param>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceFingerprint"></param>
        /// <param name="DeviceData"></param>
        /// <param name="DeviceDisplay"></param>
        public void InsertLoginLog(int UserId, bool IsSuccess, string Message, DateTime LoginTime, string IpAddress, string DeviceType, string DeviceFingerprint, string DeviceData, string DeviceDisplay)
        {
            var sql = $@"INSERT INTO `Account_LoginLog`(`UserId`,`IsSuccess`,`Message`,`LoginTime`,`IpAddress`,`DeviceType`,`DeviceFingerprint`,`DeviceData`,`DeviceDisplay`)VALUES(@UserId,@IsSuccess,@Message,@LoginTime,@IpAddress,@DeviceType,@DeviceFingerprint,@DeviceData,@DeviceDisplay);";
            db.ExecuteNonQuery(sql, new { UserId, IsSuccess, Message, LoginTime, IpAddress, DeviceType, DeviceFingerprint, DeviceData, DeviceDisplay });
        }
        /// <summary>
        /// 插入账号操作记录
        /// </summary>
        /// <param name="uid">被操作的账号</param>
        /// <param name="opruid">操作账号的人</param>
        /// <param name="opname">操作名称（char(20)）</param>
        /// <param name="remark">备注</param>
        public void InsertOpeartionLog(int uid, int opruid, string opname, string remark)
        {
            var sql = "INSERT INTO `Account_OperationLog`(`UserId`,`OperatorUserId`,`OperationName`,`Remark`)VALUES(@uid,@opruid,@opname,@remark);";
            db.ExecuteNonQuery(sql, new { uid, opruid, opname, remark });

        }
        #endregion

        #region Account_SMSCode
        /// <summary>
        /// 设置短信验证码
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="code"></param>
        public void SetSMSCode(string mobile, string code)
        {
            string sql = $"SELECT COUNT(*) FROM `Account_SMSCode` WHERE Mobile=@mobile;";
            var count = db.ExecuteInt32(sql, new { mobile });
            if (count > 0)
            {
                sql = "UPDATE `Account_SMSCode` SET CODE=@code,GenTime=NOW() WHERE Mobile=@mobile;";
            }
            else
            {
                sql = "INSERT INTO `Account_SMSCode`( Mobile, CODE) VALUES(@mobile,@code);";
            }
            db.ExecuteNonQuery(sql, new { mobile, code });
        }
        /// <summary>
        /// 获取上次发送短信的时间
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public DateTime GetLastSMSTime(string mobile)
        {
            string sql = $"SELECT GenTime FROM `Account_SMSCode` WHERE Mobile=@mobile;";
            var obj = db.ExecuteScalar<DateTime>(sql, new { mobile });

            return obj;
        }
        /// <summary>
        /// 检查是否允许发送短信(返回值大于0表示需要等待的秒数。)
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="timeSpan"></param>
        public double CheckAllowSendSMS(string mobile, TimeSpan timeSpan)
        {
            var lasttime = GetLastSMSTime(mobile);
            var ts = DateTime.Now - lasttime;
            if (ts < timeSpan)
            {
                return (timeSpan - ts).TotalSeconds;
            }
            return 0;
        }
        /// <summary>
        /// 获取短信验证码
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="timeout">超时时长</param>
        public string GetSMSCode(string mobile, TimeSpan timeout)
        {
            string sql = $"SELECT `CODE`,`GenTime` FROM `Account_SMSCode` WHERE Mobile=@mobile;";
            JObject obj = db.ExecuteJObject(sql, new { mobile });
            if (obj == null)
            {
                return null;
            }
            var gentime = obj["GenTime"].ToObject<DateTime>();
            if ((DateTime.Now - gentime) > timeout)
            {//该验证码已超时
                return null;
            }
            return obj["CODE"].ToString();
        }
        /// <summary>
        /// 匹配手机号与验证码
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="code">验证码</param>
        /// <param name="timeout">验证码有效时长</param>
        /// <returns></returns>
        public bool MatchSMSCode(string mobile, string code, TimeSpan timeout)
        {
            if (string.IsNullOrEmpty(code))
            {
                return false;
            }
            var dbcode = GetSMSCode(mobile, timeout);
            return code == dbcode;
        }
        /// <summary>
        /// 确认短信验证码是否正确
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="code"></param>
        /// <param name="timeout"></param>
        public void EnsureSMSCode(string mobile, string code, TimeSpan timeout)
        {
            if (!MatchSMSCode(mobile, code, timeout))
            {
                throw new Exception("短信验证码错误。");
            }
        }

        #endregion
    }
    /// <summary>
    /// 用户状态
    /// </summary>
    public enum UserStatus : int
    {
        /// <summary>
        /// 正常
        /// </summary>
        Normal = 0,
        /// <summary>
        /// 禁用
        /// </summary>
        Unenabled = -1,
        /// <summary>
        /// 可疑
        /// </summary>
        Doubtful = 77
    }
}
